package com.fitso.model.dao.hibernate;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;

@Component("HibernateBaseDao")
public class HibernateBaseDao {

	@Resource(name = "HibernateTemplate")
	private HibernateTemplate _hibernateTemplate;

	/**
	 * Returns back the {@link HibernateTemplate} that was injected for this DAO
	 * 
	 * @return template
	 * @see {@link #t()}
	 */
	public HibernateTemplate getTemplate() {
		return _hibernateTemplate;
	}

	/**
	 * Shorthand method for getting the {@link HibernateTemplate}
	 * 
	 * @return template
	 * @see {@link #getTemplate()}
	 */
	public HibernateTemplate t() {
		return getTemplate();
	}

	/**
	 * Returns the first object in a list, or null if list is null or empty.
	 * Useful because the spring template only returns Lists.
	 * 
	 * @param <T>
	 *            ServingSizeType of object to ruturn
	 * @param list
	 *            list object returned by spring's template
	 * @param clazz
	 *            type of object the list should be returning
	 * @return
	 */
	public <T> T first(List<T> list, Class<T> type) {
		return list == null || list.isEmpty() ? null : to(list.get(0), type);
	}

	/**
	 * Returns the first object in a raw list, or null if list is null or empty.
	 * Useful because the spring template only returns raw Lists. This is
	 * similar to @{link {@link #first(List, Class)} except this can take in an
	 * untyped {@link List} without causing a compiler warning
	 * 
	 * @param <T>
	 *            ServingSizeType of object to return
	 * @param list
	 *            list object returned by spring's template
	 * @param clazz
	 *            type of object the list should be returning
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public <T> T firstItem(List list, Class<T> type) {
		return (T) first(list, type);
	}

	/**
	 * Converts a generic object to the provided type
	 * 
	 * @param <T>
	 *            type of the returned object
	 * @param obj
	 *            to be converted
	 * @param type
	 *            to convert the ojb to
	 * @return the converted object
	 */
	public <T> T to(Object obj, Class<T> type) {
		return obj == null ? null : type.cast(obj);
	}

	/**
	 * Converts an untyped {@link List} to a typed {@link List}
	 * 
	 * @param <T>
	 *            type of the list
	 * @param list
	 *            to be typed
	 * @param type
	 *            of generic list
	 * @return generic typed list
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public <T> List<T> toList(List list, Class<T> type) {
		return (List<T>) list;
	}
}
